package com.example.moban.base;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.example.moban.utils.FeiLogUtil;
import com.example.moban.utils.Lerist;
import com.example.moban.utils.SharedPreferenceUtils;
import com.rzhd.coursepatriarch.common.utils.ScreenSizeUtils;
import com.rzhd.coursepatriarch.common.utils.rxbus.RxBus;
import com.rzhd.coursepatriarch.common.utils.rxbus.RxBusBaseMessage;


import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;


/**
 * Fragment基类
 * <p>
 * 1、Viewpager + Fragment情况下，fragment的生命周期因Viewpager的缓存机制而失去了具体意义
 * 该抽象类自定义新的回调方法，当fragment可见状态改变时会触发的回调方法，和 Fragment 第一次可见时会回调的方法
 * <p>
 * Created by yql on 2018/4/27.
 */

public abstract class BaseFragment extends Fragment implements View.OnClickListener {

    protected final String TAG = getClass().getSimpleName();

    public Activity mContext;
    private FrameLayout mContentViewWithFragment;

    private Unbinder unbinder;

    protected SharedPreferenceUtils preferenceUtils;

    private boolean mIsSoftKeyboardShowing;
    private boolean isPopBottomLayout;
    private int endHeight;
    private float topViewEndHeight;
    private boolean isOpenKeyboarded;

    protected static final int LOAD_WAY_REFRESH = 1;
    protected static final int LOAD_WAY_LOADMORE = 2;

    /**
     * 当Fragment与Activity发生关联时调用。(获得全局的，防止使用getActivity()为空)
     *
     * @param context
     */
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.mContext = (Activity) context;
    }

    /**
     * 系统会在创建Fragment时调用此方法。可以初始化一段资源文件等等。
     *
     * @param savedInstanceState
     */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    /**
     * 系统会在Fragment首次绘制其用户界面时调用此方法。 要想为Fragment绘制 UI，从该方法中返回的 View 必须是Fragment布局的根视图。如果Fragment未提供 UI，您可以返回 null。
     *
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.e(TAG, "onCreateView");
        View rootView = inflater.inflate(com.rzhd.coursepatriarch.common.R.layout.fragment_base, container, false);
        if (mContentViewWithFragment == null) {
            mContentViewWithFragment = rootView.findViewById(com.rzhd.coursepatriarch.common.R.id.mContentViewWithFragment);
            setContentView(mContentViewWithFragment, savedInstanceState);
            //必须要放在初始化view后  使用view之前
            unbinder = ButterKnife.bind(this, rootView);
            preferenceUtils = SharedPreferenceUtils.getInstance( getContext() );
            initView(rootView);
            initData();
        }
        return rootView;
    }

    /**
     * 在Fragment被绘制后，调用此方法，可以初始化控件资源。(在onCreateView立即执行)
     *
     * @param view
     * @param savedInstanceState
     */
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.e(TAG, "onViewCreated");
    }

    /**
     * 当Activity的onCreate方法返回时调用(当onCreate()，onCreateView()，onViewCreated()方法执行完后调用，也就是Activity被渲染绘制出来后。)
     *
     * @param savedInstanceState
     */
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    /**
     * 表示activity中的fragment的师徒被移除时回调的方法
     */
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        try {
            if (null != unbinder) {
                unbinder.unbind();
            }
            Log.e(TAG, "onDestroyView");
        }catch (Exception e){
            FeiLogUtil.i("fei",e.toString());
        }

    }

    /**
     * 表示fragment被销毁时回调的方法
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy");
        RxBus.getInstance().unSubscribe(this);
    }

    /**
     * 表示activity与fragment失去关联时回调的方法
     */
    @Override
    public void onDetach() {
        super.onDetach();
    }

    /**
     * 设置布局
     */
    public abstract void setContentView(FrameLayout contentView, Bundle savedInstanceState);

    /**
     * 初始化View
     */
    public abstract void initView(View view);

    /**
     * 初始化数据
     */
    public abstract void initData();


    /*--------------------------------------界面跳转--------------------------------------*/

    /***
     * 关闭界面
     */
    public void finishActivity() {
        mContext.finish();
    }

    /**
     * @param cls 目标activity 跳转并finish当前activity
     * @throws ActivityNotFoundException
     */
    public void jumpActivity(Class<?> cls) {
        showActivity(cls);
        mContext.finish();
    }

    /***
     * @param intent
     */
    public void jumpActivity(Intent intent) {
        super.startActivity(intent);
        mContext.finish();
    }

    /**
     * @param cls    目标界面
     * @param extras 需要传输的值
     */
    public void jumpActivity(Class<?> cls, Bundle extras) {
        Intent intent = new Intent();
        intent.putExtras(extras);
        intent.setClass(mContext, cls);
        startActivity(intent);
        mContext.finish();
    }

    /***
     * @param intent
     */
    public void showActivity(Intent intent) {
        super.startActivity(intent);
    }

    /**
     * @param cls 目标界面
     */
    public void showActivity(Class<?> cls) {
        Intent intent = new Intent();
        intent.setClass(mContext, cls);
        super.startActivity(intent);
    }

    /**
     * @param cls    目标界面
     * @param extras 传值数据
     */
    public void showActivity(Class<?> cls, Bundle extras) {
        Intent intent = new Intent();
        intent.setClass(mContext, cls);
        intent.putExtras(extras);
        super.startActivity(intent);
    }

    /**
     * @param cls         目标界面
     * @param requestCode 请求码
     */
    public void showActivity(Class<?> cls, int requestCode) {
        Intent intent = new Intent();
        intent.setClass(mContext, cls);
        super.startActivityForResult(intent, requestCode);
    }

    /**
     * @param cls         目标界面
     * @param extras      传值数据
     * @param requestCode 请求码
     */
    public void showActivity(Class<?> cls, Bundle extras, int requestCode) {
        Intent intent = new Intent();
        intent.setClass(mContext, cls);
        intent.putExtras(extras);
        super.startActivityForResult(intent, requestCode);
    }

    /**
     * 订阅消息
     *
     * @param code     消息类型
     * @param consumer
     */
    protected void addSubscription(@RxBusBaseMessage.EventCode int code, Consumer<RxBusBaseMessage> consumer) {
        Disposable disposable = RxBus.getInstance().toObservable(code, RxBusBaseMessage.class, consumer, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Log.e(TAG, "addSubscription  error" + throwable.toString());
            }
        });
        //保存订阅对象  方便取消订阅
        RxBus.getInstance().addSubscription(this, disposable);
    }

    /**
     * 其他额外操作(点击首页中的长城人脉右边的更多按钮时要使用)
     */
    protected void extraOpe( Bundle bundle ){

    }

    /*--------------------------------界面数据处理----------------------------------*/

    /**
     * 是否登录
     *
     * @return
     */
    protected boolean isLogin() {
        return SharedPreferenceUtils.getInstance(mContext).getLogin();
    }

    /**
     * 这两个方法在我的收藏页面使用
     */
    public void showOrHideCheckBoxOfItem( int state ){

    }

    public void cancelCollectOpe(){

    }

    /**
     * 软键盘监听器
     */
    protected ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            onGlobalLayoutMethodTwo();
        }
    };

    private void onGlobalLayoutMethodTwo() {
        int screenHeight = ScreenSizeUtils.getInstance( getActivity() ).getScreenHeight();
        //判断窗口可见区域大小
        Rect r = new Rect();
        getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
        //如果屏幕高度和Window可见区域高度差值大于整个屏幕高度的1/3，则表示软键盘显示中，否则软键盘为隐藏状态。
        int heightDifference = screenHeight - (r.bottom - r.top);
        boolean isKeyboardShowing = heightDifference > screenHeight / 3;

        //如果之前软键盘状态为显示，现在为关闭，或者之前为关闭，现在为显示，则表示软键盘的状态发生了改变
        if ((mIsSoftKeyboardShowing && !isKeyboardShowing) || (!mIsSoftKeyboardShowing && isKeyboardShowing)) {
            mIsSoftKeyboardShowing = isKeyboardShowing;
        }
        changeViewPlace(mIsSoftKeyboardShowing, r);
    }

    /**
     * 改变view的位置
     *
     * @param mIsSoftKeyboardShowing 是否显示软键盘
     * @param rect                   屏幕可视区矩形对象，通过该对象可以获取可视区的相关坐标和高度
     */
    protected void changeViewPlace(boolean mIsSoftKeyboardShowing, Rect rect) {
    }

    protected void refreshPublishLayout(   final View bottomMaskingView, Rect rect,float firstHeight ,  KeybordListener listener) {
        refreshPublishLayout( null , bottomMaskingView , null ,  rect , firstHeight , 0 , listener );
    }

    protected void refreshPublishLayout(  final View topMaskingView  , final View bottomMaskingView, Rect rect,float firstHeight ,  KeybordListener listener) {
        refreshPublishLayout( topMaskingView , bottomMaskingView , null , rect , firstHeight , 0 , listener );
    }

    protected void refreshPublishLayout(final View topMaskingView  , final View bottomMaskingView, final LinearLayout emojiContainer ,
                                        Rect rect, float firstHeight , KeybordListener listener) {
        refreshPublishLayout( topMaskingView , bottomMaskingView , emojiContainer ,   rect , firstHeight , 0 , listener );
    }

    /**
     * 刷新发布信息的布局视图
     *
     * @param bottomMaskingView
     * @param rect
     */
    protected void refreshPublishLayout( final View topMaskingView ,
                                         final View bottomMaskingView, final LinearLayout emojiContainer ,
                                         Rect rect,  float firstHeight , int differenceValue  , KeybordListener listener) {
        if (mIsSoftKeyboardShowing) {
            if (!isPopBottomLayout) {
                endHeight = ScreenSizeUtils.getInstance( getActivity() ).getScreenHeight() - rect.bottom - differenceValue;
                if( emojiContainer != null ){
                    emojiContainer.setVisibility( View.VISIBLE );
                    endHeight -= emojiContainer.getHeight();
                }
                topViewEndHeight = rect.bottom - firstHeight - Lerist.getStatusBarHeight( getContext()) - Lerist.dip2px(getContext(), 27);
                bottomMaskingView.setMinimumHeight( rect.bottom );
                //当设备系统版本高于5.0时才显示底部视图，否则会出现输入框被顶到界面最上边
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    bottomMaskingView.setVisibility(View.VISIBLE);
                }
                showPublishViewAnim( topMaskingView , bottomMaskingView,0, endHeight,
                        new MyAnimListener() {
                            @Override
                            public void onAnimationEnd() {
                                if( topMaskingView != null )topMaskingView.setVisibility(View.VISIBLE);
                                bottomMaskingView.setVisibility(View.VISIBLE);
                                isPopBottomLayout = true;
                            }
                        });
                return;
            }
            if (listener != null) {
                listener.showKeybordCallback();
            }
            isOpenKeyboarded = true;
        } else {
            if (isOpenKeyboarded) {
                showPublishViewAnim( topMaskingView , bottomMaskingView,endHeight, 0,
                        new MyAnimListener() {
                            @Override
                            public void onAnimationEnd() {
                                if( topMaskingView != null )topMaskingView.setVisibility(View.GONE);
                                bottomMaskingView.setVisibility(View.GONE);
                                isPopBottomLayout = false;
                            }
                        });
                if (listener != null) {
                    listener.closeKeybordCallback();
                }
                elseExtraOpe();
                isOpenKeyboarded = false;
            }
        }
    }

    /**
     * 覆盖此方法来做其他操作
     */
    protected void elseExtraOpe() {
    }

    /**
     * 显示发布内容弹窗动画
     *
     * @param heiChangeView
     * @param heiStartValue
     * @param heiEndValue
     * @param listener
     */
    protected void showPublishViewAnim(final View scaleChangeView,final View heiChangeView,
                                       final float heiStartValue, final float heiEndValue, final MyAnimListener listener) {
        try {
            final ValueAnimator heightAnimator = ValueAnimator.ofFloat(heiStartValue, heiEndValue);
            heightAnimator.setDuration(1);
            heightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float value = (float) valueAnimator.getAnimatedValue();
                    heiChangeView.setMinimumHeight((int) value);
                    heiChangeView.invalidate();
                }
            });
            heightAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    if (heightAnimator != null) {
                        heightAnimator.cancel();
                        if (listener != null) {
                            listener.onAnimationEnd();
                        }
                    }
                }
            });
            heightAnimator.start();
            if (scaleChangeView != null) {
                final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(0, 1);
                alphaAnimator.setDuration(1);
                alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float alpha = (float) alphaAnimator.getAnimatedValue();
                        scaleChangeView.setAlpha(alpha);
                    }
                });
                alphaAnimator.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void viewTranslationYAnim( View view , float startValue , float endValue , MyAnimListener listener ){
        try {
            final ValueAnimator heightAnimator = ValueAnimator.ofFloat( startValue, endValue );
            heightAnimator.setInterpolator( new AccelerateDecelerateInterpolator());
            heightAnimator.setDuration(700);
            heightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float value = (float) valueAnimator.getAnimatedValue();
                    view.setTranslationY( value );
                }
            });
            heightAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    if (heightAnimator != null) {
                        heightAnimator.cancel();
                    }
                    if( listener != null ){
                        listener.onAnimationEnd();
                    }
                }
            });
            heightAnimator.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected interface MyAnimListener {
        void onAnimationEnd();
    }

    public interface KeybordListener {
        void showKeybordCallback();

        void closeKeybordCallback();
    }
}
